package cc.rengu.redp.flowable.service.impl;

import cc.rengu.redp.common.utils.DateUtil;
import cc.rengu.redp.flowable.dao.FlowDataMapper;
import cc.rengu.redp.flowable.domain.FlowData;
import cc.rengu.redp.flowable.service.FlowDataService;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import static cc.rengu.redp.common.utils.DateUtil.FULL_TIME_SPLIT_PATTERN;

@Slf4j
@Service("flowDataService")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class FlowDataServiceImpl extends ServiceImpl<FlowDataMapper, FlowData> implements FlowDataService {

    /**
     * 业务数据新增
     * @param flowData 实体类
     * @return
     */
    @Override
    public Long saveFlowData(FlowData flowData) {
        // 数据库数据
        FlowData fd = this.baseMapper.selectOne(new LambdaQueryWrapper<FlowData>().eq(FlowData::getProcInstId, flowData.getProcInstId()));
        // 存在即更新
        if (null != fd){
            // 数据库业务数据
            JSONObject busiJSON = JSONObject.parseObject(fd.getFlowData());
            // 前端传来的业务数据
            JSONObject webJSON = JSONObject.parseObject(flowData.getFlowData());
            // 整合的业务数据
            JSONObject json = new JSONObject();
            // 更新数据库业务数据
            // 循环转换
            Iterator iter = busiJSON.entrySet().iterator();
            // 检查数据库中原有的业务数据信息
            while (iter.hasNext()) {
                Map.Entry entry = (Map.Entry) iter.next();
                // 判断是否存在与前端相同key的业务数据
                if (webJSON.get(entry.getKey()) != null && !"".equals(webJSON.get(entry.getKey()))){
                    // 不为空时更新数据库业务数据
                    json.put((String) entry.getKey(),webJSON.get(entry.getKey()));
                }else {
                    // 为空时保留数据库业务数据
                    json.put((String) entry.getKey(),entry.getValue());
                }
            }
            iter = webJSON.entrySet().iterator();
            // 检查前端传来新增的业务数据信息
            while (iter.hasNext()) {
                Map.Entry entry = (Map.Entry) iter.next();
                // 检查数据库业务数据信息
                if (busiJSON.get(entry.getKey()) == null || "".equals(busiJSON.get(entry.getKey()))){
                    // 为空时添加前端传来的业务数据
                    json.put((String) entry.getKey(),webJSON.get(entry.getKey()));
                }
            }
            // 将处理好的数据业务数据赋值给前端传来的业务数据
            flowData.setFlowData(json.toJSONString());
            modifiedFlowData(flowData);
            return flowData.getId();
        }else {
            if (save(flowData)) {
                return flowData.getId();
            }
        }

        return null;
    }

    /**
     * 业务数据修改（仅更新业务数据字段）
     * @param flowData 业务数据
     */
    @Override
    public void modifiedFlowData(FlowData flowData) {
        LambdaUpdateWrapper<FlowData> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.set(FlowData::getFlowData, flowData.getFlowData());
        lambdaUpdateWrapper.set(FlowData::getLastUpdateTime, DateUtil.getDateFormat(new Date(), FULL_TIME_SPLIT_PATTERN));
        if (StringUtils.isNotBlank(flowData.getProcInstId())) {
            lambdaUpdateWrapper.eq(FlowData::getProcInstId, flowData.getProcInstId());
        } else {
            lambdaUpdateWrapper.eq(FlowData::getId, flowData.getId());
        }
        this.update(lambdaUpdateWrapper);
    }

    @Override
    public void fixProcInstId(Long id, String procInstId) {
        LambdaUpdateWrapper<FlowData> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.set(FlowData::getProcInstId, procInstId).eq(FlowData::getId, id);
        this.update(lambdaUpdateWrapper);
    }

    /**
     * 业务数据删除
     * @param procDefIds 进程Ids
     */
    @Override
    public void deleteFlowData(String[] procDefIds) {
        List<String> list = Arrays.asList(procDefIds);
        removeByIds(list);
    }

    /**
     * 通过流程定义Id查询业务数据
     * @return FlowData
     */
    @Override
    public FlowData getFlowData(String procInstId) {
        return this.baseMapper.selectOne(new LambdaQueryWrapper<FlowData>().eq(FlowData::getProcInstId, procInstId));
    }
}
